/**
 * Description: UploadAction.java
 * Copyright (c) 2008-2009  Neo. 
 * All Rights Reserved.
 * @version 1.0  Mar 27, 2009 9:00:31 PM 李萌（neolimeng@gmail.com）created
 */
package org.paradise.dms.web.action.upload;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.directwebremoting.annotations.RemoteProxy;
import org.paradise.dms.poi.NeoPoiUtil;
import org.paradise.dms.poi.PoiUtil;
import org.paradise.dms.pojo.DormitoryRate;
import org.paradise.dms.pojo.Student;
import org.paradise.dms.services.DormitoryService;
import org.paradise.dms.services.StudentService;
import org.paradise.dms.util.DateUtil;
import org.paradise.dms.util.ExcelFieldsToValidate;
import org.paradise.dms.util.Utils;
import org.paradise.dms.util.ValidateExcelFields;
import org.paradise.dms.web.action.DMSBaseAction;
import org.paradise.dms.web.tools.Pager;
import org.paradise.dms.web.tools.PagerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Description: Copyright (c) 2008-2009 Neo. All Rights Reserved.
 * 
 * @version 1.0 Mar 27, 2009 9:00:31 PM 李萌（neolimeng@gmail.com）created
 */
@RemoteProxy(name = "uploadAction")
@Service
public class UploadAction extends DMSBaseAction {
	private static Logger log = Logger.getLogger(UploadAction.class);

	private static final long serialVersionUID = -8148516952934043835L;
	// 封装文件标题请求参数的属性
	private String title;
	private String studentno;// 上传学生照片时的学号。
	private List<Student> ls;

	@Autowired
	private StudentService studentservice;
	@Autowired
	private DormitoryService dormitoryService;

	// @Autowired
	// private ExcelFieldsToValidate excelEields;
	@Autowired
	private ValidateExcelFields validateExcelFields;
	@Autowired
	private PagerService pagerService;
	private Pager pager;
	protected String currentPage;
	protected String totalRows;
	protected String pagerMethod;

	// 封装上传文件域的属性
	private File uploadedFile;
	// 封装上传文件类型的属性
	private String uploadedFileContentType;
	// 封装上传文件名的属性
	private String uploadedFileFileName;

	// 直接在struts.xml文件中配置的属性
	private String savePath;
	private String studentPicSavePath;
	private String studentExcelSavePath;
	private String dormRatingResultSavePath;

	// 学生记录总数
	private int total = 0;
	// 上传成功条数
	private int success = 0;
	// 上传失败条数
	private int fail = 0;
	// 是否上传完成
	private int complete = 0;

	private static String progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-1}";

	public static boolean cancel = false;
	// 当EXCEL与系统中数据有差异时，以EXCEL为准还是以系统为准
	private boolean doExcel = false;

	public static boolean isCancel() {
		return cancel;
	}

	public static void setCancel(boolean cancel) {
		UploadAction.cancel = cancel;
	}

	@SuppressWarnings("deprecation")
	public String getDormRatingResultSavePath() {
		return ServletActionContext.getRequest().getRealPath(
				dormRatingResultSavePath);
	}

	public void setDormRatingResultSavePath(String dormRatingResultSavePath) {
		this.dormRatingResultSavePath = dormRatingResultSavePath;
	}

	// 接受struts.xml文件配置值的方法
	public void setSavePath(String value) {
		this.savePath = value;
	}

	public void setStudentPicSavePath(String studentPicSavePath) {
		this.studentPicSavePath = studentPicSavePath;
	}

	public void setStudentExcelSavePath(String studentExcelSavePath) {
		this.studentExcelSavePath = studentExcelSavePath;
	}

	// 返回上传文件的保存位置
	@SuppressWarnings("deprecation")
	private String getSavePath() throws Exception {
		return ServletActionContext.getRequest().getRealPath(savePath);
	}

	@SuppressWarnings("deprecation")
	public String getStudentPicSavePath() {// 保存学生照片的路径
		return ServletActionContext.getRequest()
				.getRealPath(studentPicSavePath);
	}

	@SuppressWarnings("deprecation")
	public String getStudentExcelSavePath() {// 保存包含学号的Excel的路径
		return ServletActionContext.getRequest().getRealPath(
				studentExcelSavePath);
	}

	// 文件标题的setter和getter方法
	public void setTitle(String title) {
		this.title = title;
	}

	public String getTitle() {
		return (this.title);
	}

	// 上传文件对应文件内容的setter和getter方法

	public File getUploadedFile() {
		return uploadedFile;
	}

	public void setUploadedFile(File uploadedFile) {
		this.uploadedFile = uploadedFile;
	}

	public String getUploadedFileContentType() {
		return uploadedFileContentType;
	}

	public void setUploadedFileContentType(String uploadedFileContentType) {
		this.uploadedFileContentType = uploadedFileContentType;
	}

	public String getUploadedFileFileName() {
		return uploadedFileFileName;
	}

	public void setUploadedFileFileName(String uploadedFileFileName) {
		this.uploadedFileFileName = uploadedFileFileName;
	}

	/**
	 * 
	 * Description: 取得上传文件的扩展名
	 * 
	 * @Version1.0 Apr 11, 2009 9:51:24 AM 李萌（neolimeng@gmail.com）创建
	 * @return
	 */
	public String getExtention() {
		if (null == uploadedFileFileName) {
			return "-1";
		}
		int pos = this.uploadedFileFileName.lastIndexOf(".");
		return this.uploadedFileFileName.substring(pos);
	}

	/**
	 * 
	 * Description:通用上传方法
	 * 
	 * @Version1.0 Apr 11, 2009 9:51:07 AM 李萌（neolimeng@gmail.com）创建
	 * @return
	 * @throws Exception
	 */
	public String uploadFile() throws Exception {
		// 以服务器的文件保存地址和原文件名建立上传文件输出流
		FileOutputStream fos = new FileOutputStream(getSavePath() + "\\"
				+ this.getSavePath());
		System.out.println(getSavePath() + "\\"
				+ this.getUploadedFileFileName());
		FileInputStream fis = new FileInputStream(this.getUploadedFile());
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = fis.read(buffer)) > 0) {
			fos.write(buffer, 0, len);
		}
		fis.close();
		fos.close();
		return SUCCESS;
	}

	/**
	 * 
	 * Description: 上传学生照片
	 * 
	 * @Version1.0 Apr 11, 2009 9:50:49 AM 李萌（neolimeng@gmail.com）创建
	 * @return
	 * @throws FileNotFoundException
	 * @throws Exception
	 */
	public String uploadStudentPicture() throws FileNotFoundException,
			Exception {
		// 以服务器的文件保存地址和原文件名建立上传文件输出流
		String studentPicFileName = this.getStudentno() + this.getExtention();
		FileOutputStream fos = new FileOutputStream(this
				.getStudentPicSavePath()
				+ "\\" + studentPicFileName);
		FileInputStream fis = new FileInputStream(this.getUploadedFile());
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = fis.read(buffer)) > 0) {
			fos.write(buffer, 0, len);
		}
		fis.close();
		fos.close();
		return SUCCESS;
	}

	/**
	 * 
	 * Description: 上传含有学号的Excel文件，并处理
	 * 
	 * @Version1.0 Apr 11, 2009 9:50:22 AM 李萌（neolimeng@gmail.com）创建
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public String uploadStudentExcel() throws IOException {
		// 以服务器的文件保存地址和原文件名建立上传文件输出流
		String studentNoExcelFileName = new Date().getTime()
				+ this.getUploadedFileFileName();
		FileOutputStream fos = new FileOutputStream(this
				.getStudentExcelSavePath()
				+ "\\" + studentNoExcelFileName);
		FileInputStream fis = new FileInputStream(this.getUploadedFile());
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = fis.read(buffer)) > 0) {
			fos.write(buffer, 0, len);
		}
		PoiUtil poiUtil = new PoiUtil();
		List list = poiUtil.poiReadExcel(this.getStudentExcelSavePath() + "\\"
				+ studentNoExcelFileName, 1, 0, 0);
		for (int i = 0; i < list.size(); i++) {
			Object[] obj = (Object[]) list.get(i);
			for (int j = 0; j < obj.length; j++) {
				log.info("Excel输出：" + obj[j].toString());
			}
		}
		String[] studentno = new String[list.size()];
		for (int i = 0; i < list.size(); i++) {
			Object[] obj = (Object[]) list.get(i);
			studentno[i] = obj[0].toString();
		}

		fis.close();
		fos.close();
		int totalRow = studentservice.getAllStudentRowsByStudentNo(studentno);
		pager = pagerService.getPager(this.getCurrentPage(), this
				.getPagerMethod(), totalRow);
		this.setCurrentPage(String.valueOf(pager.getCurrentPage()));
		log.info(pager.toString());
		log.info(pager.getCurrentPage());
		this.setTotalRows(String.valueOf(totalRow));
		ls = this.studentservice.getAllStudentPerPageByStudentNo(studentno,
				pager.getPageSize(), pager.getStartRow());
		if (ls != null && ls.size() > 0) {
			return SUCCESS;
		}
		return INPUT;
	}

	/**
	 * 
	 * Description: The method is used to handle the request of uploading
	 * student info from an Excel file to the database.
	 * 
	 * 1)The method first get the uploaded Excel file from the browser, 2)and
	 * then read the data in the file. 3)Finally the method insert the student
	 * info into the database.
	 * 
	 * @Version1.0 Apr 23, 2009 2:32:17 AM 李萌（neolimeng@gmail.com）创建
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public String uploadStudentInfo() throws IOException {
		// Get the file from the browse and write the file to preassigned path.
		// 以服务器的文件保存地址和原文件名建立上传文件输出流
		String studentNoExcelFileName = new Date().getTime()
				+ this.getUploadedFileFileName();
		FileOutputStream fos = new FileOutputStream(this
				.getStudentExcelSavePath()
				+ "\\" + studentNoExcelFileName);
		FileInputStream fis = new FileInputStream(this.getUploadedFile());
		byte[] buffer = new byte[1024];
		int len = 0;
		// Read the uploaded file, and write the file to preassigned path.
		while ((len = fis.read(buffer)) > 0) {
			fos.write(buffer, 0, len);
		}
		// Use POI to read the uploaded Excel file.
		PoiUtil poiUtil = new PoiUtil();
		// Columns to read.
		String s = ServletActionContext.getRequest().getSession().getAttribute(
				"s").toString();
		String[] scolumnsToRead = s.split(",");
		int[] columnsToRead = new int[scolumnsToRead.length];
		for (int t = 0; t < scolumnsToRead.length; t++) {
			columnsToRead[t] = Integer.parseInt(scolumnsToRead[t]);// Cast the
			// String
			// type to
			// int.
		}
		List list = poiUtil.poiReadExcel(this.getStudentExcelSavePath() + "\\"
				+ studentNoExcelFileName, 0, 1, columnsToRead);
		// Get the List contains the correct data.
		List correctList = (List) list.get(0);
		// lsv is used to store the error rows.
		List<ExcelFieldsToValidate> lsv = new ArrayList<ExcelFieldsToValidate>();
		int m = 0;
		for (int i = 0; i < correctList.size(); i++) {// Loop the rows.
			Object[] obj = (Object[]) correctList.get(i);
			m++;
			// TEMP: print out the info.
			// Validate the row of data.
			ExcelFieldsToValidate excelEields = new ExcelFieldsToValidate();
			excelEields.setError(false); // 清零上一次的错误验证标志
			excelEields.setStudentno(obj[0].toString());
			excelEields.setStudentname(obj[1].toString());
			// for (int a = 0; a < 16; a++) {
			// System.out.println("---------------" + obj[a].toString());
			// }
			excelEields.setStudentenrollyear(obj[2].toString());
			excelEields.setStudenteducationyears(obj[3].toString());
			excelEields.setStudentidentitycardno(obj[4].toString());
			excelEields.setCollegeinfoid(obj[5].toString());
			excelEields.setMajorinfoid(obj[6].toString());
			excelEields.setStudentclass(obj[7].toString());
			excelEields.setStudentgender(obj[8].toString());
			excelEields.setStudentbirthday(obj[9].toString());
			excelEields.setStudentethnic(obj[10].toString());
			excelEields.setStudentpolitics(obj[11].toString());
			excelEields.setStudentbirthplace(obj[12].toString());
			excelEields.setStudentmiddleschool(obj[13].toString());
			excelEields.setStudentsecondlanguage(obj[14].toString());
			excelEields.setStudenttype(obj[15].toString());
			excelEields = this.getValidateExcelFields().validateExcelFields(
					excelEields);
			// Check whether there is any error.
			if (excelEields.isError()) {
				// there is certain error.
				lsv.add(excelEields);
				// System.out.println(excelEields.getStudentno() + "加到了错误列表");
			} else {
				Student stu = this.getValidateExcelFields()
						.ExcelFieldsToValidate_to_Student(excelEields);
				try {
					if (studentservice.insertStudent(stu)) {
						log.info("DMS_info_" + "增加学号为" + stu.getStudentno()
								+ "的学生成功!");
					} else {
						log.error("DMS_error_" + "增加学号为" + stu.getStudentno()
								+ "的学生失败!!");
					}
					System.out.println(excelEields.getStudentno()
							+ "验证无误，插入学生信息！");
				} catch (Exception e) {
					log.error("DMS_error_将Excel中、经过验证的学生信息插入数据库时出错。");
					log.error("错误原因" + e);
				}
			}

		}

		// Save the List containing error student info data into Request for
		// further operation.
		ServletActionContext.getRequest().setAttribute("errorStudentInfoList",
				lsv);
		// Get the List contains the failed row numbers.
		List failedList = (List) list.get(1);
		for (int k = 0; k < failedList.size(); k++) {// Print the failed row
			System.out.println("以下几行在从Excel中读取数据时出错（数字代表Excel中的行号）"
					+ Integer.parseInt(failedList.get(k).toString()));
		}
		if (lsv.size() == 0) {
			return SUCCESS;
		} else {
			return INPUT;
		}
	}

	/**
	 * 
	 * Description:判断来自errordata.jsp的数据 ,有关学生的导入信息
	 * 
	 * @Version1.0 Apr 24, 2009 3:08:07 PM 郑旭（zhengxu2006@gmail.com）创建
	 * @return
	 */
	public String[][] checkUpdatedErrordata(String[][] list) {
		for (int a = 0; a < list.length; a++) {
			ExcelFieldsToValidate xcl = new ExcelFieldsToValidate();
			xcl = (ExcelFieldsToValidate) this.getValidateExcelFields()
					.Object_VS_StringArr(xcl, list[a], "set");
			xcl.setError(false);
			// 验证各个字段
			xcl = this.getValidateExcelFields().validateExcelFields(xcl);
			if (xcl.isError()) {
				list[a] = (String[]) this.getValidateExcelFields()
						.Object_VS_StringArr(xcl, list[a], "get");
				log.info(xcl.getStudentno() + "加到了错误列表");
			} else {// if there is no error, insert the student info into
				Student s = this.getValidateExcelFields()
						.ExcelFieldsToValidate_to_Student(xcl);
				if (studentservice.insertStudent(s)) {
					log.info("DMS_info_" + "增加学号为" + s.getStudentno()
							+ "的学生成功!");
				} else {
					log.error("DMS_error_" + "增加学号为" + s.getStudentno()
							+ "的学生失败!!");
				}
				list[a][17] = "-1";
				try {
					// this.studentservice.insertStudent(sv.stu);
					log.info(xcl.getStudentno() + "验证无误，插入学生信息！");
				} catch (Exception e) {
					log.error("DMS_error_将Excel中、经过验证的学生信息插入数据库时出错。");
					log.error("错误原因" + e);
				}
			}

		}
		return list;
	}

	public String setColumnsToRead(String s, HttpSession session) {
		session.setAttribute("s", s);
		// ServletActionContext.getRequest().getSession().setAttribute("s", s);
		System.out.println("another" + session.getAttribute("s").toString());
		return "正确";
	}

	@SuppressWarnings("unchecked")
	public String uploadDormRatingResult() throws IOException {
		// Get the file from the browse and write the file to preassigned path.
		// 以服务器的文件保存地址和原文件名建立上传文件输出流
		this.setCancel(false);
		String dormRatingResultExcelFileName = new Date().getTime()
				+ this.getUploadedFileFileName();
		String excelFilePath = this.getDormRatingResultSavePath() + "\\"
				+ dormRatingResultExcelFileName;
		FileOutputStream fos = new FileOutputStream(excelFilePath);
		FileInputStream fis = new FileInputStream(this.getUploadedFile());
		byte[] buffer = new byte[1024];
		int len = 0;
		// Read the uploaded file, and write the file to preassigned path.
		while ((len = fis.read(buffer)) > 0) {
			fos.write(buffer, 0, len);
		}

		List resultList = new ArrayList();
		List correctList = new ArrayList();
		@SuppressWarnings("unused")
		List failedList = new ArrayList();
		int[] columnsToRead = { 0, 2, 3, 4 };// 0-宿舍ID；1-宿舍名称；2-评分时间；3-评分成绩；4-评分人
		try {
			resultList = NeoPoiUtil.poiReadExcel(excelFilePath, 0, 1,
					columnsToRead);
			correctList = (List) resultList.get(0);
			Object[] re = new Object[correctList.size()];
			DormitoryRate dr = new DormitoryRate();
			for (int i = 0; i < correctList.size(); i++) {
				re = (Object[]) correctList.get(i);
				dr.setDormitoryid(re[0] + "");
				dr.setDormitoryratedate(DateUtil.parseDate(
						DateUtil.C_DATE_PATTON_DEFAULT, re[1] + ""));
				dr.setDormitoryscore(re[2] + "");
				dr.setDormitoryrateperson(re[3] + "");
				this.dormitoryService.insertDormitoryRateFromEXCEL(dr);
				// System.out.print("宿舍ID：" + re[0]);
				// System.out.print(" 评分时间：" + re[1]);
				// System.out.print(" 分数：" + re[2]);
				// System.out.print(" 评分人：" + re[3]);
				// System.out.println();
			}
			return SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return INPUT;
		}
	}

	@SuppressWarnings("unchecked")
	public String batchUpdate() throws IOException {
		if (!".xls".equalsIgnoreCase(getExtention())) {
			System.out.println(":::::::::::::" + getExtention());
			System.out.println(!".xls".equalsIgnoreCase(getExtention()));
			System.out.println("后缀名不相等！！");
			return INPUT;
		}
		String studentNoExcelFileName = new Date().getTime()
				+ this.getUploadedFileFileName();
		FileOutputStream fos = new FileOutputStream(this
				.getStudentExcelSavePath()
				+ "\\" + studentNoExcelFileName);
		FileInputStream fis = new FileInputStream(this.getUploadedFile());
		byte[] buffer = new byte[1024];
		int len = 0;
		// Read the uploaded file, and write the file to preassigned path.
		while ((len = fis.read(buffer)) > 0) {
			fos.write(buffer, 0, len);
		}

		// Columns to read.
		int[] columnsToRead = { 0, 1, 2, 3, 4, 5 };
		List list = NeoPoiUtil.poiReadExcel(this.getStudentExcelSavePath()
				+ "\\" + studentNoExcelFileName, 0, 1, columnsToRead);

		// Get the List contains the correct data.
		List correctList = (List) list.get(0);

		/*
		 * Process the correctList: Inert student info into database.
		 * 
		 * Store the failed lines into another Excel, which will be downloaded.
		 */
		DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");

		System.out.println("===========" + correctList.size());
		List failedListToExcel = studentservice.batchUpdate(correctList);

		HttpServletResponse response = ServletActionContext.getResponse();
		String fname = "BatchUpdateStudentInfoFailedList";// Excel文件名
		OutputStream os;
		try {
			String[] titles = { "新学号", "姓名", "学院", "老学号", "考试方式", "错误提示" };

			os = response.getOutputStream();// 取得输出流
			response.reset();// 清空输出流
			response.setHeader("Content-disposition", "attachment; filename="
					+ fname + ".xls");
			// 设定输出文件头,该方法有两个参数，分别表示应答头的名字和值。
			response.setContentType("application/msexcel");

			NeoPoiUtil.poiWriteExcel(titles, failedListToExcel, os);
			return SUCCESS;
		} catch (IOException e) {
			log.error("DMS_error:无法取到OutputStream");
			log.error("DMS_error:错误原因" + e);
			return INPUT;
		}

	}

	/**
	 * 
	 * Description: 1、将上传的文件生成到指定的目录下； 2、读取该文件里面的信息，正确的插入到学生表，错误的放到临时表；
	 * 3、验证规则：（1）某些列必须有值 （2）
	 * 
	 * 
	 * @Version1.0 May 22, 2009 9:58:01 AM 李萌（neolimeng@gmail.com）创建
	 * @return
	 * @throws IOException
	 */
	// TODO:未完成
	@SuppressWarnings("unchecked")
	public String uploadFormatedStudentInfo() throws IOException {
		cancel = false;
		if (!".xls".equalsIgnoreCase(getExtention())) {
			System.out.println(":::::::::::::" + getExtention());
			System.out.println(!".xls".equalsIgnoreCase(getExtention()));
			System.out.println("后缀名不相等！！");
			progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-2}";
			return null;
		}

		// Get the file from the browse and write the file to preassigned path.
		// 以服务器的文件保存地址和原文件名建立上传文件输出流
		try {
			String studentNoExcelFileName = new Date().getTime()
					+ this.getUploadedFileFileName();
			FileOutputStream fos = new FileOutputStream(this
					.getStudentExcelSavePath()
					+ "\\" + studentNoExcelFileName);
			FileInputStream fis = new FileInputStream(this.getUploadedFile());
			byte[] buffer = new byte[1024];
			int len = 0;
			// Read the uploaded file, and write the file to preassigned path.
			while ((len = fis.read(buffer)) > 0) {
				fos.write(buffer, 0, len);
			}

			progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-1}";

			int[] columnsToRead = NeoPoiUtil.poiReadFirstRowOfExcel(this
					.getStudentExcelSavePath()
					+ "\\" + studentNoExcelFileName, 0, 0, 100);
			List list = NeoPoiUtil.poiReadExcel(this.getStudentExcelSavePath()
					+ "\\" + studentNoExcelFileName, 0, 1, columnsToRead);
			// System.out.println(ReflectionToStringBuilder.toString(
			// (Object[])list.get(0)).toString());
			// Get the List contains the correct data.
			List correctList = (List) list.get(0);
			List errorList = (List) list.get(1);
			total = correctList.size() + errorList.size();

			// 经检验数据格式正确的待插入的学生列表
			List<Student> studentlist = new ArrayList<Student>();
			List failedListToExcel = new ArrayList();

			DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
			HashSet<String> set = studentservice.getStudentNo();
			// System.out.println("@@@@@@@@@@@@@@
			// correctList.size="+correctList.size());
			for (int i = 0; i < correctList.size(); i++) {
				if (cancel) {
					progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-4}";
					return null;
				}
				Object[] obj = (Object[]) correctList.get(i);
				// 验证学生信息，如果正确，返回null，即o为null；如果有错，返回一个Object[]，即o为Object[]
				Object[] o = validateDataFromExcel(obj, set);
				if (null == o) {
					Student s = new Student();
					s.setStudentno(((String) obj[0]));
					s.setStudentname(((String) obj[1]));
					s.setStudentenrollyear(((String) obj[2]));
					s.setStudenteducationyears(((String) obj[3]));
					s.setStudentidentitycardno(((String) obj[4]));
					String college = ((String) obj[5]);
					if (null != college && !"".equals(college)) {
						s.setCollegeinfoid(Integer.parseInt(college));
					}

					String mid = ((String) obj[6]);
					if (null != mid && !"".equals(mid)) {
						try {
							s.setMajorinfoid(Integer.parseInt(mid));
						} catch (NumberFormatException e) {
							e.printStackTrace();
						}
					}
					s.setStudentclass(((String) obj[7]));
					s.setStudentgender(((String) obj[8]));
					try {
						// 转换yyyyMMdd的string 格式时间为yy-MM-dd的date格式时间
						String sb = ((String) obj[9]);
						if (null != sb && !"".equals(sb)) {
							s.setStudentbirthday(dateFormat.parse(sb));
						}

					} catch (ParseException e) {
						e.printStackTrace();
					}
					s.setStudentethnic(((String) obj[10]));
					s.setStudentpolitics(((String) obj[11]));
					s.setStudentbirthplace(((String) obj[12]));
					s.setStudentmiddleschool(((String) obj[13]));
					s.setStudentsecondlanguage(((String) obj[14]));
					s.setStudenttype(((String) obj[15]));
					s.setStudentmisc(((String) obj[16]));
					s.setStudentadmissiontype(((String) obj[17]));
					s.setStudentycsj(((String) obj[18]));
					s.setStudentadvisorname(((String) obj[19]));
					s.setStudentind(1);
					studentlist.add(s);
					success += 1;
					progress = "{\"total\":" + total + ",\"success\":"
							+ success + ",\"fail\":" + fail + ",\"complete\":"
							+ complete + "}";
					continue;
				}
				if (o != null && "学号已存在".equals((String) o[24])) {
					Student s = studentservice.getStudentByStudentNo(
							((String) obj[0]).trim()).get(0);
					Object[] old = new Object[25];
					old[0] = s.getStudentno();
					old[1] = s.getStudentname();
					old[2] = s.getStudentenrollyear();
					old[3] = s.getStudenteducationyears();
					old[4] = s.getStudentidentitycardno();
					old[5] = s.getCollegeinfoid();
					old[6] = s.getMajorinfoid();
					old[7] = s.getStudentclass();
					old[8] = s.getStudentgender();
					old[9] = s.getStudentbirthday();
					old[10] = s.getStudentethnic();
					old[11] = s.getStudentethnic();
					old[12] = s.getStudentbirthplace();

					old[13] = s.getStudentmiddleschool();
					old[14] = s.getStudentsecondlanguage();
					old[15] = s.getStudenttype();
					old[16] = s.getStudentmisc();
					old[17] = s.getStudentadmissiontype();
					old[18] = s.getStudentycsj();
					old[19] = s.getStudentadvisorname();

					old[20] = s.getStudentgraduatedate();
					old[21] = s.getStudentflfx();
					old[22] = "";
					old[23] = "原数据库记录";
					old[24] = "compare";
					failedListToExcel.add(old);
					failedListToExcel.add(o);
				} else {
					failedListToExcel.add(o);
				}
				fail += 1;
				progress = "{\"total\":" + total + ",\"success\":" + success
						+ ",\"fail\":" + fail + ",\"complete\":" + complete
						+ "}";
			}
			progress = "{\"total\":" + total + ",\"success\":" + success
					+ ",\"fail\":" + fail + ",\"complete\":2" + "}";
			complete = studentservice.batchInsert(studentlist);
			progress = "{\"total\":" + total + ",\"success\":" + success
					+ ",\"fail\":" + fail + ",\"complete\":" + complete + "}";

			if (failedListToExcel != null && failedListToExcel.size() > 0) {
				HttpServletResponse response = ServletActionContext
						.getResponse();
				String fname = "UploadStudentInfoFailedList";// Excel文件名
				OutputStream os;
				try {
					String[] titles = { "学号", "姓名", "入学年份", "学制", "身份证", "学院",
							"专业代码", "班级", "性别", "出生日期", "民族", "政治面貌", "生源地",
							"毕业学校", "语种", "层次", "备注", "培养方式", "因材施教", "博导姓名",
							"毕业时间", "分流方向", "备用", "错误标识", "错误原因" };
					os = response.getOutputStream();// 取得输出流
					response.reset();// 清空输出流
					response.setHeader("Content-disposition",
							"attachment; filename=" + fname + ".xls");
					// 设定输出文件头,该方法有两个参数，分别表示应答头的名字和值。
					response.setContentType("application/msexcel");

					NeoPoiUtil.poiWriteExcel(titles, failedListToExcel, os);
					// return SUCCESS;
				} catch (IOException e) {
					log.error("DMS_error:无法取到OutputStream");
					log.error("DMS_error:错误原因" + e);
					return null;
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-3}";
		}
		return null;
	}

	// 判断两个字符串是否相等
	private boolean compare(String src, String dest) {
		if (!Utils.notNull(src) && !Utils.notNull(dest)) {
			return true;
		}
		if (Utils.notNull(src)) {
			if (src.equals(dest)) {
				return true;
			}
		}
		if (Utils.notNull(dest)) {
			if (dest.equals(src)) {
				return true;
			}
		}
		return false;
	}

	// TODO:未完成
	@SuppressWarnings("unchecked")
	public String validateStudentInfo() throws IOException {
		cancel = false;
		if (!".xls".equalsIgnoreCase(getExtention())) {
			progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-2}";
			return null;
		}

		try {
			String studentNoExcelFileName = new Date().getTime()
					+ this.getUploadedFileFileName();
			FileOutputStream fos = new FileOutputStream(this
					.getStudentExcelSavePath()
					+ "\\" + studentNoExcelFileName);
			FileInputStream fis = new FileInputStream(this.getUploadedFile());
			byte[] buffer = new byte[1024];
			int len = 0;
			// Read the uploaded file, and write the file to preassigned path.
			while ((len = fis.read(buffer)) > 0) {
				fos.write(buffer, 0, len);
			}

			progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-1}";

			int[] columnsToRead = NeoPoiUtil.poiReadFirstRowOfExcel(this
					.getStudentExcelSavePath()
					+ "\\" + studentNoExcelFileName, 0, 0, 100);
			List list = NeoPoiUtil.poiReadExcel(this.getStudentExcelSavePath()
					+ "\\" + studentNoExcelFileName, 0, 1, columnsToRead);
			List correctList = (List) list.get(0);
			List errorList = (List) list.get(1);
			total = correctList.size() + errorList.size();

			// 经检验数据格式正确的待插入的学生列表
			List<Student> studentlist = new ArrayList<Student>();
			List failedListToExcel = new ArrayList();

			DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
			HashSet<String> set = studentservice.getStudentNo();
			for (int i = 0; i < correctList.size(); i++) {
				if (cancel) {
					progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-4}";
					return null;
				}
				Object[] obj = (Object[]) correctList.get(i);
				// 验证学生信息，如果正确，返回null，即o为null；如果有错，返回一个Object[]，即o为Object[]
				String s;
				// 学号
				s = (obj[0] != null ? (String) obj[0] : "").trim();
				Student student = studentservice
						.getStudentByStudentNo(s.trim()).get(0);
				if (null == student) {
					continue;
				}
				boolean modify = false;// 是否对系统中的数据进行了修改
				if (doExcel) {
					// 学生姓名
					s = (obj[1] != null ? (String) obj[1] : "").trim();
					if (!compare(student.getStudentname(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentname(s);
							modify = true;
						}
					}

					// 入学年份
					s = (obj[2] != null ? (String) obj[2] : "").trim();
					if (!compare(student.getStudentenrollyear(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentenrollyear(s);
							modify = true;
						}
					}

					// 学制
					s = (obj[3] != null ? (String) obj[3] : "").trim();
					if (!compare(student.getStudenteducationyears(), s)) {
						if (Utils.notNull(s)) {
							student.setStudenteducationyears(s);
							modify = true;
						}
					}

					// 身份证
					s = (obj[4] != null ? (String) obj[4] : "").trim();
					if (!compare(student.getStudentidentitycardno(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentidentitycardno(s);
							modify = true;
						}
					}

					// 学院
					s = (obj[5] != null ? (String) obj[5] : "").trim();
					if (!compare(String.valueOf(student.getCollegeinfoid()), s)) {
						if (Utils.notNull(s)) {
							student.setCollegeinfoid(Integer.parseInt(s));
							modify = true;
						}
					}

					// 专业代码
					s = (obj[6] != null ? (String) obj[6] : "").trim();
					if (!compare(String.valueOf(student.getMajorinfoid()), s)) {
						if (Utils.notNull(s)) {
							student.setMajorinfoid(Integer.parseInt(s));
							modify = true;
						}
					}

					// 班级
					s = (obj[7] != null ? (String) obj[7] : "").trim();
					if (!compare(student.getStudentclass(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentclass(s);
							modify = true;
						}
					}
					// 性别
					s = (obj[8] != null ? (String) obj[8] : "").trim();
					if (!compare(student.getStudentgender(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentgender(s);
							modify = true;
						}
					}
					// 出生日期
					s = (obj[9] != null ? (String) obj[9] : "").trim();
					if (!compare(String.valueOf(student.getStudentbirthday()),
							s)) {
						if (Utils.notNull(s)) {
							student.setStudentbirthday(dateFormat.parse(s));
							modify = true;
						}
					}

					// 民族
					s = (obj[10] != null ? (String) obj[10] : "").trim();
					if (!compare(student.getStudentethnic(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentethnic(s);
							modify = true;
						}
					}
	
					// 政治面貌
					s = (obj[11] != null ? (String) obj[11] : "").trim();
					if (!compare(student.getStudentpolitics(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentpolitics(s);
							modify = true;
						}
					}
					
					// 生源地
					s = (obj[12] != null ? (String) obj[12] : "").trim();
					if (!compare(student.getStudentbirthplace(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentbirthplace(s);
							modify = true;
						}
					}
					// 毕业学校
					s = (obj[13] != null ? (String) obj[13] : "").trim();
					if (!compare(student.getStudentmiddleschool(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentmiddleschool(s);
							modify = true;
						}
					}
					// 语种
					s = (obj[14] != null ? (String) obj[14] : "").trim();
					if (!compare(student.getStudentsecondlanguage(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentsecondlanguage(s);
							modify = true;
						}
					}
					
					// 层次
					s = (obj[15] != null ? (String) obj[15] : "").trim();
					if (!compare(student.getStudenttype(), s)) {
						if (Utils.notNull(s)) {
							student.setStudenttype(s);
							modify = true;
						}
					}
					// 备注
					s = (obj[16] != null ? (String) obj[16] : "").trim();
					if (!compare(student.getStudentmisc(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentmisc(s);
							modify = true;
						}
					}
					// 培养方式
					s = (obj[17] != null ? (String) obj[17] : "").trim();
					if (!compare(student.getStudentadmissiontype(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentadmissiontype(s);
							modify = true;
						}
					}
					// "层次", "备注", "培养方式", "因材施教", "博导姓名", "毕业时间", "分流方向", "备用",
					// "错误标识", "错误原因"
					//因材施教
					s = (obj[18] != null ? (String) obj[18] : "").trim();
					if (!compare(student.getStudentycsj(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentycsj(s);
							modify = true;
						}
					}
					//导师姓名
					s = (obj[19] != null ? (String) obj[19] : "").trim();
					if (!compare(student.getStudentadvisorname(), s)) {
						if (Utils.notNull(s)) {
							student.setStudentadvisorname(s);
							modify = true;
						}
					}
					student.setStudentind(1);
					studentlist.add(student);
					success += 1;
					progress = "{\"total\":" + total + ",\"success\":"
							+ success + ",\"fail\":" + fail + ",\"complete\":"
							+ complete + "}";
					continue;
				} else {

				}
				
				fail += 1;
				progress = "{\"total\":" + total + ",\"success\":" + success
						+ ",\"fail\":" + fail + ",\"complete\":" + complete
						+ "}";
			}
			progress = "{\"total\":" + total + ",\"success\":" + success
					+ ",\"fail\":" + fail + ",\"complete\":2" + "}";
			complete = studentservice.batchInsert(studentlist);
			progress = "{\"total\":" + total + ",\"success\":" + success
					+ ",\"fail\":" + fail + ",\"complete\":" + complete + "}";

			if (failedListToExcel != null && failedListToExcel.size() > 0) {
				HttpServletResponse response = ServletActionContext
						.getResponse();
				String fname = "UploadStudentInfoFailedList";// Excel文件名
				OutputStream os;
				try {
					String[] titles = { "学号", "姓名", "入学年份", "学制", "身份证", "学院",
							"专业代码", "班级", "性别", "出生日期", "民族", "政治面貌", "生源地",
							"毕业学校", "语种", "层次", "备注", "培养方式", "因材施教", "博导姓名",
							"毕业时间", "分流方向", "备用", "错误标识", "错误原因" };
					os = response.getOutputStream();// 取得输出流
					response.reset();// 清空输出流
					response.setHeader("Content-disposition",
							"attachment; filename=" + fname + ".xls");
					// 设定输出文件头,该方法有两个参数，分别表示应答头的名字和值。
					response.setContentType("application/msexcel");

					NeoPoiUtil.poiWriteExcel(titles, failedListToExcel, os);
					// return SUCCESS;
				} catch (IOException e) {
					log.error("DMS_error:无法取到OutputStream");
					log.error("DMS_error:错误原因" + e);
					return null;
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			progress = "{\"total\":0,\"success\":0,\"fail\":0,\"complete\":-3}";
		}
		return null;
	}

	// ------------------验证来自excel的数据-----------------
	public Object[] validateDataFromExcel(Object[] obj, HashSet<String> set) {
		Object[] o;
		String s;
		// 学号
		s = (obj[0] != null ? (String) obj[0] : "").trim();
		if ("".equals(s)) {
			o = new Object[25];
			System.arraycopy(obj, 0, o, 0, 23);
			o[23] = false;
			o[24] = "学号不能为空";
			return o;

		} else if (null != set && set.contains(s)) {
			o = new Object[25];
			System.arraycopy(obj, 0, o, 0, 23);
			o[23] = false;
			o[24] = "学号已存在";
			return o;
		}
		// 姓名
		s = (obj[1] != null ? (String) obj[1] : "").trim();
		if ("".equals(s)) {
			o = new Object[25];
			System.arraycopy(obj, 0, o, 0, 23);
			o[23] = false;
			o[24] = "姓名不能为空";
			return o;

		}
		// 入学年份
		s = (obj[2] != null ? (String) obj[2] : "").trim();
		if ("".equals(s)) {
			o = new Object[25];
			System.arraycopy(obj, 0, o, 0, 23);
			o[23] = false;
			o[24] = "入学年份不能为空";
			return o;

		} else if (!regex(s, "^[0-9]{4}$")) {
			o = new Object[25];
			System.arraycopy(obj, 0, o, 0, 23);
			o[23] = false;
			o[24] = "入学年份必须是4位数字";
			return o;
		}
		// TODO:学制 有点五的情况
		s = (obj[3] != null ? (String) obj[3] : "").trim();
		if ("".equals(s)) {
			o = new Object[25];
			System.arraycopy(obj, 0, o, 0, 23);
			o[23] = false;
			o[24] = "学制不能为空";
			return o;

		} else if (!regex(s, "^[0-9]$")) {
			o = new Object[25];
			System.arraycopy(obj, 0, o, 0, 23);
			o[23] = false;
			o[24] = "学制必须为1位数字";
			return o;
		}

		// 学院
		s = (obj[5] != null ? (String) obj[5] : "").trim();
		if (!"".equals(s)) {
			Integer in = Integer.valueOf(s);
			if (in > 12 || in < 1) {
				o = new Object[25];
				System.arraycopy(obj, 0, o, 0, 23);
				o[23] = false;
				o[24] = "学院代码格式不正确，应在1-12之内";
				return o;
			}
		}

		// 出生日期
		s = (obj[9] != null ? (String) obj[9] : "").trim();
		if (!"".equals(s)) {
			if (!regex(
					s,
					"^(\\d{4})(/|-)?(0\\d{1}|1[0-2])(/|-)?(0\\d{1}|[12]\\d{1}|3[01])(\\s00:00:00.0)?$")) {
				o = new Object[25];
				System.arraycopy(obj, 0, o, 0, 23);
				o[23] = false;
				o[24] = "出生日期不正确";
				return o;
			}
		}
		return null;
	}

	/**
	 * 
	 * Description: 正则表达式验证
	 * 
	 * @Version1.0 May 22, 2009 3:26:41 PM 郑旭（zhengxu2006@gmail.com）创建
	 * @param matcher
	 * @param pattern
	 * @return
	 */
	public boolean regex(String matcher, String pattern) {
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(matcher);
		boolean b = m.matches();
		// 当条件满足时，将返回true，否则返回false
		return b;
	}

	public String validateCollege(String college) {
		String so = college.trim();
		if (!"".equals(so)) {
			if (so.indexOf("土木") != -1) {
				college = "1";
			} else if (so.indexOf("冶金") != -1 && so.indexOf("研究院") == -1) {
				college = "2";
			} else if (so.indexOf("材料") != -1 && so.indexOf("中心") == -1
					&& so.indexOf("实验室") == -1) {
				college = "3";
			} else if (so.indexOf("机械") != -1) {
				college = "4";
			} else if (so.indexOf("信息") != -1) {
				college = "5";
			} else if (so.indexOf("应用") != -1) {
				college = "6";
			} else if (so.indexOf("管理") != -1 || so.indexOf("经管") != -1) {
				college = "7";
			} else if (so.indexOf("文法") != -1) {
				college = "8";
			} else if (so.indexOf("外国语") != -1 || so.indexOf("外语") != -1) {
				college = "9";
			} else if (so.indexOf("新金属") != -1) {
				college = "10";
			} else if (so.indexOf("冶金工程研究院") != -1) {
				college = "11";
			} else if (so.indexOf("教育部材料服役安全科学中心") != -1) {
				college = "12";
			} else {
				int collegeid = studentservice.getCollegeIdByName(so);
				return collegeid + "";
			}
			return college;
		} else
			return "-1";
	}

	public JSONObject getProgress() {
		JSONObject json = new JSONObject().fromObject(progress);
		return json;
	}

	public void cancel() {
		cancel = true;
	}

	public String getStudentno() {
		return studentno;
	}

	public void setStudentno(String studentno) {
		this.studentno = studentno;
	}

	public List<Student> getLs() {
		return ls;
	}

	public void setLs(List<Student> ls) {
		this.ls = ls;
	}

	public StudentService getStudentservice() {
		return studentservice;
	}

	public void setStudentservice(StudentService studentservice) {
		this.studentservice = studentservice;
	}

	public PagerService getPagerService() {
		return pagerService;
	}

	public void setPagerService(PagerService pagerService) {
		this.pagerService = pagerService;
	}

	public Pager getPager() {
		return pager;
	}

	public void setPager(Pager pager) {
		this.pager = pager;
	}

	public String getCurrentPage() {
		return currentPage;
	}

	public void setCurrentPage(String currentPage) {
		this.currentPage = currentPage;
	}

	public String getTotalRows() {
		return totalRows;
	}

	public void setTotalRows(String totalRows) {
		this.totalRows = totalRows;
	}

	public String getPagerMethod() {
		return pagerMethod;
	}

	public void setPagerMethod(String pagerMethod) {
		this.pagerMethod = pagerMethod;
	}

	public ValidateExcelFields getValidateExcelFields() {
		return validateExcelFields;
	}

	public void setValidateExcelFields(ValidateExcelFields validateExcelFields) {
		this.validateExcelFields = validateExcelFields;
	}

	public DormitoryService getDormitoryService() {
		return dormitoryService;
	}

	public void setDormitoryService(DormitoryService dormitoryService) {
		this.dormitoryService = dormitoryService;
	}

	public boolean isDoExcel() {
		return doExcel;
	}

	public void setDoExcel(boolean doExcel) {
		this.doExcel = doExcel;
	}
}
